package com.hymjweb.demo.hymj.native_bill_manage.service;

import com.alibaba.fastjson.JSONObject;
import com.hymjweb.demo.SpringAopUtil;
import com.hymjweb.demo.framework.result.MIniUIGridResultMap;
import com.hymjweb.demo.framework.sys.BaseService;
import com.hymjweb.demo.framework.sys.SysConstant;
import com.hymjweb.demo.framework.util.DataTypeUtil;
import com.hymjweb.demo.framework.util.DateUtil;
import com.hymjweb.demo.framework.util.DoubleUtil;
import com.hymjweb.demo.framework.util.pojoContrast.ContrastUtils;
import com.hymjweb.demo.framework.util.util.PoiUtil;
import com.hymjweb.demo.hymj.basic_data_manage.xt_upload_file.bean.XtUploadFilePojo;
import com.hymjweb.demo.hymj.basic_data_manage.xt_upload_file.service.XtUploadFileService;
import com.hymjweb.demo.hymj.bill_code_manage.b_native.service.BillNativeCodeService;
import com.hymjweb.demo.hymj.log_manage.aop.annotation.OperationLogger;
import com.hymjweb.demo.hymj.log_manage.bean.XtBackupLogMsgPojo;
import com.hymjweb.demo.hymj.log_manage.service.XtBackupLogMsgService;
import com.hymjweb.demo.hymj.master_bill_manage.load.bean.BNativeBillLoadPojo;
import com.hymjweb.demo.hymj.master_bill_manage.load.service.BNativeBillLoadService;
import com.hymjweb.demo.hymj.master_bill_manage.pull.detail.bean.BMasterBillPullDetailPojo;
import com.hymjweb.demo.hymj.master_bill_manage.pull.detail.service.BMasterBillPullDetailService;
import com.hymjweb.demo.hymj.native_bill_manage.bean.BNativeBillPojo;
import com.hymjweb.demo.hymj.native_bill_manage.mappper.BNativeBillMapper;
import com.hymjweb.demo.hymj.native_bill_manage.other_charges.bean.BNativeBillOtherCharges;
import com.hymjweb.demo.hymj.native_bill_manage.other_charges.service.BNativeBillOtherChargesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
@Service
public class BNativeBillService extends BaseService {

    @Autowired
    private BNativeBillMapper bNativeBillMapper;

    @Autowired
    private BNativeBillOtherChargesService bNativeBillOtherChargesService;

    @Autowired
    private BillNativeCodeService billNativeCodeService;

    @Autowired
    private BNativeBillLoadService bNativeBillLoadService;

    @Autowired
    private BMasterBillPullDetailService bMasterBillPullDetailService;

    @Autowired
    private XtBackupLogMsgService xtBackupLogMsgService;

    @Autowired
    private XtUploadFileService xtUploadFileService;

    @Autowired
    private ContrastUtils contrastUtils;

    public static final int NATIVE_BILL_EXSIT = -10; // 分单已经存在


    private static final Double DEFAULT_AMOUNT = -999999999D;


    /**
     * 分单查询
     *
     * @param param 查询参数
     * @return 返回页面对象
     */
    public Object getPageList(Map<String, Object> param) {
        // 设置公共查询参数,加上部门
        this.setQueryCommParam(param);
        this.pageListInit(param);
        List list = getNoPageList(param);
        MIniUIGridResultMap resultMap = this.pageToGrid(list);
        return resultMap;
    }

    /**
     * 根据发货人ID查询曾经的收货人
     *
     * @param param 查询参数
     * @return
     */
    public Object queryBillReceiveCustomerByDeliveryCustomerId(Map<String, Object> param) {
        // 设置公共查询参数,加上部门
        this.setQueryCommParam(param);
        this.pageListInit(param);
        List<Map<String, Object>> line_list = bNativeBillMapper.queryBillReceiveCustomerByDeliveryCustomerId(param);
        List<Map<String, Object>> list = DataTypeUtil.lineMapToHumpMap2(line_list);
        MIniUIGridResultMap resultMap = this.pageToGrid(list);
        return resultMap;
    }

    /**
     * 无分页查询
     *
     * @param param
     * @return
     */
    public List<BNativeBillPojo> getDailyReportList(Map<String, Object> param) {
        // 加入公共参数
        this.setQueryCommParam(param);
        List<BNativeBillPojo> list = bNativeBillMapper.getDailyReportList(param);
        return list;
    }

    /**
     * 无分页查询
     *
     * @param param
     * @return
     */
    public List<BNativeBillPojo> getNoPageList(Map<String, Object> param) {
        return bNativeBillMapper.findAll(param);
    }

    public List<BNativeBillPojo> getBNativeBillPojoListByInId(String billIds) throws Exception {
        if (DataTypeUtil.isEmptyStr(billIds)) {
            throwException("根据分单ids加载分单对象参数错误!");
        }
        return bNativeBillMapper.getBNativeBillPojoListByInId(billIds);
    }

    /**
     * 根据分单id查询并返回分单对象
     *
     * @param id
     * @return
     */
    public BNativeBillPojo getBNativeBillPojoById(String id) throws Exception {
        if (DataTypeUtil.isEmptyStr(id)) {
            throwException("获取分单对象参数错误");
        }
        BNativeBillPojo pojo = bNativeBillMapper.getBNativeBillPojoById(id);
        if (DataTypeUtil.isEmptyStr(id)) {
            throwException("根据分单ID检索分单对象失败!");
        }
        // 获取分单对应的其他费用列表对象
        List<BNativeBillOtherCharges> bNativeBillOtherCharges = bNativeBillOtherChargesService.getOtherChargesListByBillId(id);
        if (pojo != null) {
            pojo.setOtherChargeList(bNativeBillOtherCharges);
        }
        return pojo;
    }

    /**
     * 根据 key 进行模糊检索
     *
     * @param parma
     * @return
     */
    public List<BNativeBillPojo> getBNativeBillPojoByCnd(Map parma) {
        // 1.从分单表中提取数据b_native_bill
        List<BNativeBillPojo> list = bNativeBillMapper.getBNativeBillPojoByCnd(parma);

        List<BNativeBillPojo> list2 = new ArrayList<>();
        if (list != null && list.size() > SysConstant.INT_ZERO) {
            // 遍历这个 list,把已经配载了信息给减去
            for (BNativeBillPojo pojo : list) {
                Map<String, Object> loadTotalNativeMap = bNativeBillLoadService.getLoadTotalNativeMap(pojo.getId());
                if (loadTotalNativeMap != null) {
                    Map<String, Object> humpMap = DataTypeUtil.lineMapToHumpMap(loadTotalNativeMap);
                    // 获取值
                    // sum(ifnull(t.flight_load_number,0)) total_load_number,
                    // sum(ifnull(t.flight_load_actual_weight,0)) total_load_actual_weight,
                    // sum(ifnull(t.flight_load_chargeable_weight,0)) total_load_chargeable_weight,
                    // sum(ifnull(t.flight_load_volume,0)) total_load_volume
                    Integer totalLoadNumber = DataTypeUtil.toInt(Integer.parseInt(humpMap.get("totalLoadNumber").toString()), 0);
                    Double totalLoadActualWeight = DataTypeUtil.toDouble(humpMap.get("totalLoadActualWeight"), 0);
                    Double totalLoadChargeableWeight = DataTypeUtil.toDouble(humpMap.get("totalLoadChargeableWeight"), 0);
                    Double totalLoadVolume = DataTypeUtil.toDouble(humpMap.get("totalLoadVolume"), 0);
                    // 需要用原来的总件数 - 拉货件数 - 已经配载的件数，这才是最后要显示到前端可供配载的件数
                    Integer pojoNumber = DataTypeUtil.toInt(pojo.getTotalNumber(), 0) - DataTypeUtil.toInt(pojo.getRefundNumber(), 0);
                    pojo.setTotalNumber(pojoNumber - totalLoadNumber);
                    pojo.setActualWeight(DoubleUtil.sub(DataTypeUtil.toDouble(pojo.getActualWeight(), 0), totalLoadActualWeight, 2));
                    pojo.setChargeableWeight(DoubleUtil.sub(DataTypeUtil.toDouble(pojo.getChargeableWeight(), 0), totalLoadChargeableWeight, 2));
                    pojo.setVolume(DoubleUtil.sub(DataTypeUtil.toDouble(pojo.getVolume(), 0), totalLoadVolume, 2));
                }
                // && pojo.getVolume()>SysConstant.ZERO 体积条件去了
                if (pojo.getTotalNumber() > SysConstant.INT_ZERO && (pojo.getActualWeight() > SysConstant.ZERO || pojo.getChargeableWeight() > SysConstant.ZERO)) {
                    list2.add(pojo);
                }
            }
        }

        // 2.由于可能会有改配的情况，还需要从拉货配载表中检索对应的数据 b_master_bill_pull与b_master_bill_pull_detail 条件是pull_dispose_id(232)处置类型为改配
        List<BMasterBillPullDetailPojo> pullDetailPojos = bMasterBillPullDetailService.getReloadList(parma);
        if (pullDetailPojos != null && pullDetailPojos.size() > SysConstant.INT_ZERO) {
            // pullDetailPojos 这是在配载时符合改配的数据列表
            for (BMasterBillPullDetailPojo pojo : pullDetailPojos) {
                BNativeBillPojo nativeBillPojo = bNativeBillMapper.getBNativeBillPojoById(pojo.getNativeBillId());
                // b_master_bill_pull
                // BMasterBillPullPojo bMasterBillPullPojo = bMasterBillPullService.getBMasterBillPullPojoById(pojo.getMasterBillPullId());
                if (nativeBillPojo != null) {
                    nativeBillPojo.setTotalNumber(DataTypeUtil.toInteger(pojo.getPullNumber()));
                    nativeBillPojo.setActualWeight(pojo.getPullActualWeight());
                    nativeBillPojo.setChargeableWeight(pojo.getPullChargeableWeight());
                    nativeBillPojo.setVolume(pojo.getPullVolume());

                    nativeBillPojo.setAirlinesId(pojo.getPullDisposeAirlinesId());
                    nativeBillPojo.setAirportId(pojo.getPullDisposeAirportId());
                    nativeBillPojo.setFlightNo(pojo.getPullDisposeFlightNo());
                    nativeBillPojo.setFlightName(pojo.getPullDisposeFlightName());
                    nativeBillPojo.setFlightDate(pojo.getPullDisposeFlightDate());

                    list2.add(nativeBillPojo);
                }
            }
        }
        return list2;
    }


    //@OperationLogger(oper = SysConstant.OPER_ADD, operTitle = "分单-新增", operMemo = "", classType = BNativeBillPojo.class)
    @Transactional(rollbackFor = {Exception.class})
    public int insert(BNativeBillPojo pojo) {
        return bNativeBillMapper.insert(pojo);
    }

    /**
     * 新分单入库
     *
     * @param pojo
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int addNativeBill(BNativeBillPojo pojo) throws Exception {

        if (pojo == null) {
            throwException("添加分单参数错误!");
        }

        // 1.检测分单号是否重复
        BNativeBillPojo checkPojo = bNativeBillMapper.getBNativeBillPojoById(pojo.getId());

        if (checkPojo != null) {
            return BNativeBillService.NATIVE_BILL_EXSIT;
        }

        // 判断业务费与代理送货费用的状态，为0时则直接为已经结费
        if (pojo.getServiceCharge().doubleValue() == SysConstant.ZERO.doubleValue()) {
            pojo.setBusinessCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }
        else{
            pojo.setBusinessCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }

        if (pojo.getAgentDeliveryCharge().doubleValue() == SysConstant.ZERO.doubleValue()) {
            pojo.setAgentDeliveryChargeStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }
        else {
            pojo.setAgentDeliveryChargeStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }

        // 判断代理送货费对账状态
        if(pojo.getAgentDeliveryCharge().doubleValue() == SysConstant.ZERO.doubleValue()){
            pojo.setAgentDeliveryChargeAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
        }

        // 指定的分单不存在可以添加分单
        int addAffectRows = SpringAopUtil.getBean(this.getClass()).insert(pojo);

        // 分单插入成功，判断是否有分单其他费用明细，如果有，则添加明细
        if (addAffectRows > 0) {
            // 插入分单其他费用
            List<BNativeBillOtherCharges> otherCharges = pojo.getOtherChargeList();
            if (otherCharges != null && !otherCharges.isEmpty()) {
                // 批量插入
                int batchAddAffectRows = bNativeBillOtherChargesService.batchInsert(otherCharges);
                if (batchAddAffectRows <= SysConstant.INT_ZERO) {
                    return SysConstant.INT_ZERO;
                }
            }
            // 标识分单号已经被使用
            int statusUpdateAffectRows = billNativeCodeService.updateBillCodeStatus(pojo.getId(), SysConstant.XT_DIC_USE_STATUS.USED.getId(), this.getSystemUserDepartment().getId(), this.getLoginCzyId());
            if (statusUpdateAffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }
        }
        return addAffectRows;
    }

    @OperationLogger(oper = SysConstant.OPER_UPDATE, operTitle = "分单-更新", operMemo = "", classType = BNativeBillPojo.class)
    @Transactional(rollbackFor = {Exception.class})
    public int update(BNativeBillPojo pojo) throws Exception {
        if (pojo == null) {
            throwException("更新的分单对象参数错误!");
        }
        return bNativeBillMapper.update(pojo);
    }

    /**
     * 更新分单对象
     *
     * @param pojo
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateNativeBill(BNativeBillPojo pojo) throws Exception {


        BNativeBillPojo oldPojo = getBNativeBillPojoById(pojo.getId());

        // 检测配载状态
        Long billLoadStatus = oldPojo.getBillLoadStatusId();
        if(billLoadStatus.longValue() == SysConstant.XT_DIC_BILL_LOAD_STATUS.ALL_LOAD.getId() || billLoadStatus.longValue() == SysConstant.XT_DIC_BILL_LOAD_STATUS.PART_LOAD.getId()){
            throwException("分单已全部配载或部分配载，不能做更新操作,如需更新需把分单从主单配载中退出!");
        }

        // 判断分单的结算对账状态
        if(oldPojo.getAccountCheckStatusId().longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()){
            throwException("分单已对账，不能更新!");
        }

        if(oldPojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()){
            throwException("分单已结算，不能更新!");
        }

        // 判断业务费与代理送货费用的状态，为0时则直接为已经结费
        if (pojo.getServiceCharge().doubleValue() == SysConstant.ZERO.doubleValue()) {
            pojo.setBusinessCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }
        else{
            pojo.setBusinessCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }

        if (pojo.getAgentDeliveryCharge().doubleValue() == SysConstant.ZERO.doubleValue()) {
            pojo.setAgentDeliveryChargeStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }
        else {
            pojo.setAgentDeliveryChargeStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }

        // 判断代理送货费对账状态
        if(pojo.getAgentDeliveryCharge().doubleValue() == SysConstant.ZERO.doubleValue()){
            pojo.setAgentDeliveryChargeAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
        }

        // 设置结算金额
        pojo.setSettlementAmount(DoubleUtil.sum(pojo.getTotalAmount(),pojo.getDropAmount(),2));
        pojo.setShareCost(SysConstant.ZERO);
        pojo.setGrossProfit(SysConstant.ZERO);
        pojo.setShareCostComment("");

        // 更新分单对象
        int updateAffectRows = SpringAopUtil.getBean(this.getClass()).update(pojo);

        if (updateAffectRows <= SysConstant.INT_ZERO) {
            throwException("更新分单对象失败!");
        }

        // 删除原来的分单其他费用的列表
        bNativeBillOtherChargesService.deleteByBillId(pojo.getId());

        List<BNativeBillOtherCharges> otherCharges = pojo.getOtherChargeList();

        if (otherCharges != null && !otherCharges.isEmpty()) {
            bNativeBillOtherChargesService.batchInsert(otherCharges);
        }

        return updateAffectRows;
    }


    /**
     * 非价格信息更新
     * @param pojo
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateSaveNativeBill(BNativeBillPojo pojo) throws Exception {
        if (pojo == null) {
            throwException("更新的分单对象参数错误!");
        }


        BNativeBillPojo oldPojo = getBNativeBillPojoById(pojo.getId());
        if(oldPojo==null){
            throwException("待更新分单对象在数据库中不存在,更新失败");
        }



//        // 重新设定分单结算金额
//        pojo.setSettlementAmount(DoubleUtil.sum(pojo.getActualAmount(),pojo.getDropAmount(),2));
//        // 检测一下分单是否已经全部配载了
//        Map<String,Object> param = new HashMap<>();
//        param.put("billId",pojo.getId());
//        List<BNativeBillLoadPojo> bNativeBillLoadPojoList = bNativeBillLoadService.queryNativeBillListNoPage(param);
//        Integer totalLoadNumber = SysConstant.INT_ZERO;
//        for(BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList){
//            totalLoadNumber += loadPojo.getLoadNumber().intValue();
//        }
//
//        if(totalLoadNumber.intValue() == pojo.getTotalNumber().intValue()){
//            // 全部配载了利润重新算
//            // 毛利润=分单结算金额(settlement_amount) - 业务费(service_charge) - 代理送货费(agent_delivery_charge) - 分单分摊成本(share_cost)-锦添操作费(operating_cost这个操作费还没有定，要给出解决方案,现在不考虑)
//            Double grossProfit = DoubleUtil.round2(pojo.getSettlementAmount() - pojo.getServiceCharge() - pojo.getAgentDeliveryCharge() - pojo.getShareCost() - pojo.getOperatingCost());
//            pojo.setGrossProfit(grossProfit);
//        }

        // 调用非价格信息更新
        return SpringAopUtil.getBean(this.getClass()).nonPriceUpdate(pojo);
    }


    @OperationLogger(oper = SysConstant.OPER_UPDATE, operTitle = "分单-非价格信息更新", operMemo = "", classType = BNativeBillPojo.class)
    @Transactional(rollbackFor = {Exception.class})
    public int nonPriceUpdate(BNativeBillPojo pojo) throws Exception{
        return bNativeBillMapper.updateSaveNativeBill(pojo);
    }


    /**
     * 将前端接收来的json对象转为java对象
     *
     * @param billJsonObj 页面传入的json对象
     * @return 返回对象
     */
    public BNativeBillPojo convertJSONObjToJavaObj(JSONObject billJsonObj, String opType) throws Exception {

        if (billJsonObj == null || billJsonObj.isEmpty() || DataTypeUtil.isEmptyStr(opType)) {
            throwException("分单对象转换失败!");
        }

        BNativeBillPojo pojo = billJsonObj.toJavaObject(BNativeBillPojo.class);

        // 计算结算金额 = 总金额 + 拉货金额
        Double settlementAmount = DoubleUtil.sum(pojo.getTotalAmount(), pojo.getDropAmount(), 2);
        pojo.setSettlementAmount(settlementAmount);

        // 设置其他费用列的分单号
        for (BNativeBillOtherCharges otherChargesPojo : pojo.getOtherChargeList()) {
            otherChargesPojo.setId(this.getSysStrId());
            otherChargesPojo.setNativeBillId(pojo.getId());
        }

        // 设置日期
        Date currentDate = DateUtil.getSysDateTime();
        String currentUserId = this.getLoginCzyId();

        /**
         * 只有添加时才需要设置
         */
        if (opType.equals(SysConstant.OPER_ADD)) {
            pojo.setCreateTime(currentDate);
            pojo.setCreateUserId(currentUserId);

            // 分单开单时什么情况下是直接结费状态???
        }

        pojo.setUpdateTime(currentDate);
        pojo.setUpdateUserId(currentUserId);

        return pojo;
    }


    /**
     * 更新分单配载状态
     *
     * @param billId
     * @param loadStatusId
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateLoadStatus(String billId, long loadStatusId) throws Exception {
        if (DataTypeUtil.isEmptyStr(billId)) {
            throwException("更新分单位配载状态参数错误!");
        }
        String statusFieldName = "bill_load_status_id";
        int affectRow = updateStatusId(statusFieldName, loadStatusId, billId, this.getSysTime(), this.getLoginCzyId());
        return affectRow;
    }

    /**
     * 更新分状态，根据 billIds,格式如 'aa','bb','cc'
     *
     * @param statusFieldName
     * @param billIds
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateStatusId(String statusFieldName, Long statusId, String billIds, Date updateTime, String updateUserId) throws Exception {
        // 先获取改变状态前的列表
        List<BNativeBillPojo> oldList = getBNativeBillPojoListByInId(billIds);
        int affectRow = bNativeBillMapper.updateStatusId(statusFieldName, statusId, billIds, updateTime, updateUserId);
        // 再获取改变状态后的列表
        List<BNativeBillPojo> newList = getBNativeBillPojoListByInId(billIds);

        List<XtBackupLogMsgPojo> xtBackupLogMsgPojoList = new ArrayList<>();

        for (BNativeBillPojo oldPojo : oldList) {
            String id = oldPojo.getId();
            for (BNativeBillPojo newPojo : newList) {
                String newId = newPojo.getId();
                if (id.equals(newId)) {
                    // 下面再根据相应的状态做比较
                    try {
                        String msg = contrastUtils.compareTwoObj(SysConstant.OPER_UPDATE, oldPojo, newPojo);
                        if (msg.length() > 0) {
                            XtBackupLogMsgPojo xtBackupLogMsgPojo = new XtBackupLogMsgPojo();
                            xtBackupLogMsgPojo.setId(this.getSysStrId());
                            xtBackupLogMsgPojo.setTableName("b_native_bill");
                            xtBackupLogMsgPojo.setTableId(id);
                            xtBackupLogMsgPojo.setOperTitle("分单-更新");
                            xtBackupLogMsgPojo.setOperMemo("");
                            xtBackupLogMsgPojo.setBackupLogMsg(msg.getBytes(StandardCharsets.UTF_8));
                            xtBackupLogMsgPojo.setPojoName(BNativeBillPojo.class.getName());
                            xtBackupLogMsgPojo.setCreateTime(updateTime);
                            xtBackupLogMsgPojo.setCreateUserId(updateUserId);
                            xtBackupLogMsgPojo.setCreateUserName(this.getLoginCzyName());
                            xtBackupLogMsgPojo.setCreateTimeShort(DataTypeUtil.toLong(DateUtil.date2short(updateTime)));
                            xtBackupLogMsgPojoList.add(xtBackupLogMsgPojo);
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        continue;
                    }
                }
            }
        }

        xtBackupLogMsgService.batchInsert(xtBackupLogMsgPojoList);

        return affectRow;
    }

    /**
     * 删除分单，分单参数形式为 分单号1,分单号2,分单号3
     *
     * @param param
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int deleteNativeBillByBillIds(Map param) throws Exception {
        if(param==null || param.isEmpty()){
            throwException("分单删除参数错误!");
        }
        // {billIds:cancelBillIds}
        String billIds = DataTypeUtil.toStringObject(param.get("billIds"));
        if (billIds == null) {
            throwException("分单删除参数错误!");
        }

        String[] billIdArray = billIds.split(",");
        StringBuffer billDeleteExceptionStr = new StringBuffer("");
        // 通过迭代进行删除，删除之前还需要检测分单的当前状态
        for (String billId : billIdArray) {
            BNativeBillPojo billPojo = this.getBNativeBillPojoById(billId);

            if(!DataTypeUtil.isEmptyStr(billPojo.getBillLoadMasterBillIds())){
                billDeleteExceptionStr.append(billId + ",");
            }

//            if (billPojo.getBillLoadStatusId().longValue() == SysConstant.XT_DIC_BILL_LOAD_STATUS.PART_LOAD.getId()
//                    || billPojo.getBillLoadStatusId().longValue() == SysConstant.XT_DIC_BILL_LOAD_STATUS.ALL_LOAD.getId()
//                    || billPojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
//                    || billPojo.getAccountCheckStatusId().longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
//            ) {
//                billDeleteExceptionStr.append(billId + ",");
//            }
        }

        if (billDeleteExceptionStr.length() > 0) {
            throw new Exception("分单【" + billDeleteExceptionStr.substring(0, billDeleteExceptionStr.length() - 1) + "】配载有主单号，不能删除!");
        }

        int affectRows = 0;
        for (String billId : billIdArray) {
            // 先删除分单其他费用
            List<BNativeBillOtherCharges> otherChargesList = bNativeBillOtherChargesService.getOtherChargesListByBillId(billId);
            if (otherChargesList != null && !otherChargesList.isEmpty()) {
                for (BNativeBillOtherCharges otherCharges : otherChargesList) {
                    SpringAopUtil.getBean(BNativeBillOtherChargesService.class).delete(otherCharges.getId());
                }

            }

            //int affectRow = SpringAopUtil.getBean(this.getClass()).delete(billId);
            int affectRow = this.delete(billId);
            if (affectRow > SysConstant.INT_ZERO) {
                affectRows += affectRow;
                // 恢复分单号可以使用
                billNativeCodeService.updateBillCodeStatus(billId, SysConstant.XT_DIC_USE_STATUS.UNUSED.getId(), null, null);
            }
        }

        return affectRows;
    }

    // @OperationLogger(oper = SysConstant.OPER_ADD, operTitle="分单-删除" , operMemo = "", classType = BNativeBillPojo.class)
    @Transactional(rollbackFor = {Exception.class})
    public int delete(String billId) throws Exception {
        if (DataTypeUtil.isEmptyStr(billId)) {
            throwException("分单号为空，分单删除失败！");
        }
        return bNativeBillMapper.delete(billId);
    }

    /**
     * 作废分单，分单参数形式为 '分单号1','分单号2','分单号3'
     *
     * @param param
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int cancelNativeBill(Map param) throws Exception {
        // {billIds:cancelBillIds}
        if(param==null || param.isEmpty()){
            throwException("分单删除参数错误!");
        }

        String billIds = DataTypeUtil.toStringObject(param.get("billIds"));
        if (billIds == null) {
            throwException("分单作废分单号参数错误!");
        }

        // 1. 根据 ids 获取需要作废的列表
        List<BNativeBillPojo> nativeBillPojoList = getBNativeBillPojoListByInId(billIds);
        if(nativeBillPojoList==null || nativeBillPojoList.isEmpty()){
            throwException("作废分单列表获取失败!");
        }
        // 2.检测各个分单的配载情况
        // billId
        Map<String, Integer> billLoadMap = new HashMap<>();
        Map<String, BNativeBillPojo> nativeBillPojoMap = new HashMap<>();
        for (BNativeBillPojo billPojo : nativeBillPojoList) {
            Map<String, Object> map = new HashMap<>();
            map.put("billId", billPojo.getId());
            List<BNativeBillLoadPojo> loadPojos = bNativeBillLoadService.queryNativeBillListNoPage(map);
            billLoadMap.put(billPojo.getId(), loadPojos.size());
            nativeBillPojoMap.put(billPojo.getId(), billPojo);
        }
        boolean billCanCancelFlag = true;
        // 检测是否是未配载及原始的配载状态,分单同时是未结算的状态
        for (Map.Entry<String, BNativeBillPojo> entry : nativeBillPojoMap.entrySet()) {
            String billId = entry.getKey();
            BNativeBillPojo pojo = entry.getValue();
            Integer loadSize = billLoadMap.get(billId);
            if (pojo.getBillLoadStatusId().longValue() != SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId()
                    || loadSize.intValue() != SysConstant.INT_ZERO.intValue()
                    || pojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                    || pojo.getAccountCheckStatusId().longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()) {
                billCanCancelFlag = false;
                break;
            }
        }

        if (!billCanCancelFlag) {
            throwException("选择作废的分中包含全部配载或部分配载或已对账或已结算完成的分单，不能进行作废操作!");
        }

        // 现在可以调用作废
        int affectRows = updateStatusId("cancel_status_id", SysConstant.XT_DIC_CANCEL_STATUS.CANCELED.getId(), billIds, this.getSysTime(), this.getLoginCzyId());

        return affectRows;
    }

    // {billIds:canAccountCheckIds,accountCheckStatusId:accountStatus}
    @Transactional(rollbackFor = {Exception.class})
    public int changeAccountCheckStatus(Map param) throws Exception {
        if(param==null || param.isEmpty()){
            throwException("修改分单对账状态参数错误!");
        }
        String billIds = DataTypeUtil.toStringObject(param.get("billIds"));
        Long accountCheckStatusId = DataTypeUtil.toLong(param.get("accountCheckStatusId"));

        List<BNativeBillPojo> list = getBNativeBillPojoListByInId(billIds);

        if (list == null || list.size() == 0) {
            throwException("分单对账状态修改获取分单列表失败!");
        }

        String canNotAccountCheckIds = "";

        if (accountCheckStatusId.longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()) {
            // 确认对账
            for (BNativeBillPojo pojo : list) {
                if (pojo.getBillLoadStatusId().longValue() != SysConstant.XT_DIC_BILL_LOAD_STATUS.ALL_LOAD.getId() || pojo.getCancelStatusId().longValue() == SysConstant.XT_DIC_CANCEL_STATUS.CANCELED.getId()) {
                    canNotAccountCheckIds += pojo.getId() + " ";
                }
            }
        } else {
            // 取消对账
            for (BNativeBillPojo pojo : list) {
                if (pojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()) {
                    canNotAccountCheckIds += pojo.getId() + " ";
                }
            }
        }

        if (canNotAccountCheckIds.length() > 0) {
            if (accountCheckStatusId.longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()) {
                throwException("选择的对账分单【" + canNotAccountCheckIds.trim() + "】没有全部配载或已经作废，不能进行对账确认操作!");
            } else {
                throwException("选择的对账分单【" + canNotAccountCheckIds.trim() + "】已结算，不能进行对账取消操作!");
            }
        }

        int affectRows = updateStatusId("account_check_status_id", accountCheckStatusId, billIds, this.getSysTime(), this.getLoginCzyId());

        return affectRows;
    }


    /**
     * 分单代理送货费对账状态修改
     * @param param
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int changeAgentDeliveryChargeAccountCheckStatus(Map param) throws Exception {
        if(param==null || param.isEmpty()){
            throwException("修改分单代理送货费对账状态参数错误!");
        }
        String billIds = DataTypeUtil.toStringObject(param.get("billIds"));
        Long accountCheckStatusId = DataTypeUtil.toLong(param.get("accountCheckStatusId"));

        List<BNativeBillPojo> list = getBNativeBillPojoListByInId(billIds);

        if (list == null || list.size() == 0) {
            throwException("分单代理送货费对账状态修改获取分单列表失败!");
        }

        String canNotAccountCheckIds = "";

        if (accountCheckStatusId.longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()) {
            // 确认代理送货费对账状态
            for (BNativeBillPojo pojo : list) {
                if (pojo.getBillLoadStatusId().longValue() != SysConstant.XT_DIC_BILL_LOAD_STATUS.ALL_LOAD.getId() || pojo.getCancelStatusId().longValue() == SysConstant.XT_DIC_CANCEL_STATUS.CANCELED.getId()) {
                    canNotAccountCheckIds += pojo.getId() + " ";
                }
            }
        } else {
            // 取消代理送货费对账状态
            for (BNativeBillPojo pojo : list) {
                if (pojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()) {
                    canNotAccountCheckIds += pojo.getId() + " ";
                }
            }
        }

        if (canNotAccountCheckIds.length() > 0) {
            if (accountCheckStatusId.longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()) {
                throwException("选择的对账分单【" + canNotAccountCheckIds.trim() + "】没有全部配载或已经作废，不能进行代理送货费对账状态确认操作!");
            } else {
                throwException("选择的对账分单【" + canNotAccountCheckIds.trim() + "】已结算，不能进行代理送货费对账状态取消操作!");
            }
        }

        int affectRows = updateStatusId("agent_delivery_charge_account_check_status_id", accountCheckStatusId, billIds, this.getSysTime(), this.getLoginCzyId());

        return affectRows;
    }



    /**
     * 根据主单号查询主单包含的分单列表原始对象
     *
     * @param masterBillId
     * @return
     * @throws Exception
     */
    public List<BNativeBillPojo> queryBNativeBillPojoListByMasterBillId(String masterBillId) throws Exception {
        if (DataTypeUtil.isEmptyStr(masterBillId)) {
            throwException("主单号查询分单列表参数错误!");
        }
        return bNativeBillMapper.queryBNativeBillPojoListByMasterBillId(masterBillId);
    }

    /**
     * 分单成本、利润核算，两个地方调用，一个是配载主单时调用，一个是主单拉货时调用
     *
     * @param nativeBillId 分单号
     * @param isPullGoods  是否拉货
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = {Exception.class})
    public int nativeBillCostAccounting(String nativeBillId, boolean isPullGoods) throws Exception {
        if(DataTypeUtil.isEmptyStr(nativeBillId)){
            throwException("分单号不存在,分单成本与利润核算参数错误!");
        }
        // 1.根据分单号获取分单对象
        BNativeBillPojo bNativeBillPojo = this.getBNativeBillPojoById(nativeBillId);
        if (bNativeBillPojo == null) {
            throwException("分单不存在,分单成本核算错误!");
        }

        // 2.定义分单拉货调整总金额
        Double totalDropAmount = 0D;

        // 3.如果是拉货时分单成本核算，则需要到拉货明细表中检索对应分单的拉货调整总金额
        if (isPullGoods) {
            // 设置分单拉货状态
            bNativeBillPojo.setDropStatusId(SysConstant.XT_DIC_PULL_STATUS.PULL.getId());

            // 根据分单号检索分单对应的拉货明细
            Map<String, Object> pullDetailParam = new HashMap<>();
            pullDetailParam.put("nativeBillId", nativeBillId);
            List<BMasterBillPullDetailPojo> billPullDetailPojoList = bMasterBillPullDetailService.queryPullDetailListNoPage(pullDetailParam);

            // 判断是否有拉货明细
            if (billPullDetailPojoList == null && billPullDetailPojoList.isEmpty()) {
                throwException("分单拉货明细不存在,分单拉货成本、利润核算失败!");
            }

            for (BMasterBillPullDetailPojo pullDetailPojo : billPullDetailPojoList) {
                // 累计分单拉货调整金额
                totalDropAmount += pullDetailPojo.getPullAmount();
                // 获取分单拉货时的对应处理方式
                Long pullDisposeId = DataTypeUtil.toLong(pullDetailPojo.getPullDisposeId(), -1);
                // 判断分单拉货时是不是做退客户处理,如果全拉改配呢?
                if (pullDisposeId.longValue() == SysConstant.XT_DIC_NATIVE_PULL_DISPOSE.REFUND.getId()) {
                    // 如果是做退货处理，则要设置分单上的退货信息
                    int refundNumber = bNativeBillPojo.getRefundNumber();
                    Double refundActualWeight = bNativeBillPojo.getRefundActualWeight();
                    Double refundChargeableWeight = bNativeBillPojo.getRefundChargeableWeight();
                    Double refundVolume = bNativeBillPojo.getRefundVolume();

                    bNativeBillPojo.setRefundNumber(refundNumber + DataTypeUtil.toInt(pullDetailPojo.getPullNumber()));
                    bNativeBillPojo.setRefundActualWeight(DoubleUtil.sum(refundActualWeight, pullDetailPojo.getPullActualWeight(), 2));
                    bNativeBillPojo.setRefundChargeableWeight(DoubleUtil.sum(refundChargeableWeight, pullDetailPojo.getPullChargeableWeight(), 2));
                    bNativeBillPojo.setRefundVolume(DoubleUtil.sum(refundVolume, pullDetailPojo.getPullVolume()));
                }
            }
        }

        // 4.分单拉货调整总调金额
        totalDropAmount = DoubleUtil.round2(totalDropAmount);

        // 5.设置分单的总调整金额
        bNativeBillPojo.setDropAmount(totalDropAmount);

        // 6.设置分单 结算金额 = 分单实收金额 + 分单拉货调整总金额(未拉货默认为0)
        bNativeBillPojo.setSettlementAmount(DoubleUtil.sum(bNativeBillPojo.getActualAmount(), bNativeBillPojo.getDropAmount(), 2));

        // 7.分单原始件数
        long nativeOriginalTotalNumber = bNativeBillPojo.getTotalNumber() - bNativeBillPojo.getRefundNumber();
        // 8.分单位原始计重
        Double nativeOriginalTotalChargeableWeight = DoubleUtil.sub(bNativeBillPojo.getChargeableWeight(), bNativeBillPojo.getRefundChargeableWeight(), 2);

        // 9.根据分单号获取对应分单的所有配载信息
        Map<String, Object> param = new HashMap<>();
        param.put("billId", nativeBillId);
        List<BNativeBillLoadPojo> bNativeBillLoadPojoList = bNativeBillLoadService.queryNativeBillListNoPage(param);

        // 10.设置分单被配载到哪些主单中
        bNativeBillPojo.setBillLoadMasterBillIds("");

        // 11.设置分单默认 成本、利润及成本说明
        bNativeBillPojo.setShareCost(0D);
        bNativeBillPojo.setGrossProfit(0D);
        bNativeBillPojo.setShareCostComment("");

        if (bNativeBillLoadPojoList == null && bNativeBillLoadPojoList.isEmpty()) {
            // throw new Exception("分单未配载，成本核算错误!");
            // 因为可能全部改配及全部退货，那么这个配载列表就为空，则对应的分单成本清空，不需要进行核算了,直接改为未配载
            bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId());
            return this.update(bNativeBillPojo);
        }

        // 10.累计配载信息
        // 10.1 定义累计配载件数
        long totalLoadNumber = 0L;
        // 10.2 定义累计配载计费重量
        Double totalLoadChargeableWeight = 0D;
        // 10.3 定义累计配载成本
        Double totalShareTotalCostAmount = 0D;
        // 10.4 定义分单配载所有主单ID
        String loadMasterBillIds = "";
        // 10.5 定义分单分摊成本说明信息
        List<Map<String, Object>> loadShareTotalCostCommentArray = new ArrayList<>();

        Set<String> loadMasterBillIdSet = new HashSet<>();

        for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
            loadMasterBillIdSet.add(loadPojo.getMasterBillId());
            totalLoadNumber += loadPojo.getLoadNumber();
            totalLoadChargeableWeight += loadPojo.getLoadChargeableWeight();
            totalShareTotalCostAmount += loadPojo.getShareTotalCostAmount();
            Map<String, Object> commentMap = new HashMap<>();
            commentMap.put("分单配载成本", loadPojo.getShareTotalCostComment());
            loadShareTotalCostCommentArray.add(commentMap);
        }

        // 得到分单配载的主单号
        if (!loadMasterBillIdSet.isEmpty()) {
            for (String billId : loadMasterBillIdSet) {
                loadMasterBillIds += billId + ",";
            }
        }

        if (loadMasterBillIds.length() > 0) {
            loadMasterBillIds = loadMasterBillIds.substring(0, loadMasterBillIds.length() - 1);
        }

        // 11.设置分单被配载到哪些主单中
        bNativeBillPojo.setBillLoadMasterBillIds(loadMasterBillIds);

        // 13.根据配载的件数与分单原始的件数进行比较，设置相应的状态
        if (totalLoadNumber == 0) {
            bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId());
        } else if (totalLoadNumber > 0 && totalLoadNumber < nativeOriginalTotalNumber) {
            bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.PART_LOAD.getId());
        } else {

            // 13.1 分单成本说明
            Map<String, Object> shareCostCommentMap = new LinkedHashMap<>();

            shareCostCommentMap.put("分单配载成本明细", loadShareTotalCostCommentArray);

            // 13.2 设置全部配载
            bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.ALL_LOAD.getId());

            // 13.3 设置分摊的总成本
            bNativeBillPojo.setShareCost(totalShareTotalCostAmount);
            shareCostCommentMap.put("分单配载总成本", totalShareTotalCostAmount);

            // 13.4 分单业务费
            Double serviceCharge = bNativeBillPojo.getServiceCharge();
            shareCostCommentMap.put("分单业务费", serviceCharge);

            // 13.5 分单代理送货费
            Double agentDeliveryCharge = bNativeBillPojo.getAgentDeliveryCharge();
            shareCostCommentMap.put("分单代理送货费", agentDeliveryCharge);

            // 13.6 分单提货费
            Long pickupDriverFee = bNativeBillPojo.getPickupDriverFee();
            shareCostCommentMap.put("分单提货费",pickupDriverFee);

            // 13.7 分单总成本
            Double nativeBillTotalShareCost = DoubleUtil.sum(serviceCharge + agentDeliveryCharge + pickupDriverFee + totalShareTotalCostAmount, 0, 2);
            bNativeBillPojo.setShareCost(nativeBillTotalShareCost);
            shareCostCommentMap.put("分单总成本(分单配载总成本 + 分单业务费 + 分单代理送货费 + 分单提货费)", nativeBillTotalShareCost);

            // 13.8 分单利润
            Double nativeBillTotalShareGrossProfit = DoubleUtil.sub(bNativeBillPojo.getSettlementAmount(), nativeBillTotalShareCost, 2);
            bNativeBillPojo.setGrossProfit(nativeBillTotalShareGrossProfit);
            shareCostCommentMap.put("分单利润(分单结算金额 - 分单总成本)", nativeBillTotalShareGrossProfit);

            // 13.9 设置分单成本说明
            bNativeBillPojo.setShareCostComment(JSONObject.toJSONString(shareCostCommentMap));

        }

        return this.update(bNativeBillPojo);
    }


    /**
     * 修改分单提货费
     * @param id
     * @param pickupDriverFee
     * @param pickupDriverName
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = {Exception.class})
    public int savePickupDriverFee(String id, Long pickupDriverFee, String pickupDriverName) throws Exception {
        if(DataTypeUtil.isEmptyStr(id)){
            throwException("分单ID为空!");
        }
        if(pickupDriverFee==-1L || DataTypeUtil.isEmptyStr(pickupDriverName)){
            throwException("填写分单提货费参数异常");
        }

        BNativeBillPojo bNativeBillPojo = getBNativeBillPojoById(id);
        bNativeBillPojo.setPickupDriverFee(pickupDriverFee);
        bNativeBillPojo.setPickupDriverName(pickupDriverName);

        // 调整分单总成本 = 分单原来成本 + 分单提货费
        bNativeBillPojo.setShareCost(DoubleUtil.sum(bNativeBillPojo.getShareCost(),bNativeBillPojo.getPickupDriverFee(),2));

        // 分单利润 = 分单结算费用 - 调整分单成本
        bNativeBillPojo.setGrossProfit(DoubleUtil.sub(bNativeBillPojo.getSettlementAmount(),bNativeBillPojo.getShareCost(),2));

        return this.bNativeBillMapper.update(bNativeBillPojo);
    }


    /**
     * 获取部门开单信息汇总
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public List<Map<String, Object>> queryDepartmentOpenBillCollectList(String startDate, String endDate) {
        return bNativeBillMapper.queryDepartmentOpenBillCollectList(startDate, endDate);
    }

    /**
     * 获取部门日开单量
     * @param startDate
     * @param endDate
     * @return
     */
    public List<Map<String, Object>> queryDepartmentDailyOpenBillCollectList(String startDate, String endDate) {
        return bNativeBillMapper.queryDepartmentDailyOpenBillCollectList(startDate, endDate);
    }


    public String accountFileUploadAncCheck(MultipartFile upLoadFile) throws Exception {
        // 1.上传文件
        XtUploadFilePojo filePojo = xtUploadFileService.upload(upLoadFile);

        // 2.处理对账
        String reulstMsg = processNativeBillAgentDeliveryChargeAccount(filePojo);

        return reulstMsg;
    }

    private String processNativeBillAgentDeliveryChargeAccount(XtUploadFilePojo filePojo) throws Exception {
        File destFile = xtUploadFileService.getFile(filePojo);

        // 定义读取文件的输入流
        FileInputStream fis = new FileInputStream(destFile);
        ;

        Workbook wb = PoiUtil.getWorkBook(destFile, fis);

        Sheet sheet = wb.getSheetAt(0);

        int rows = sheet.getLastRowNum();

        if (rows < 2) {
            throw new Exception("Excel文件内容为空");
        }

        // 1.按行读取所有Excel中的每一行，形成一个List<Map>
        List<Map<String, Object>> listMap = new ArrayList<>();
        // 异常处理字符串
        StringBuffer exceptionInfoStr = new StringBuffer();

        for (int i = 1; i <= rows; i++) {
            Row row = sheet.getRow(i);
            int rowNum = row.getRowNum() + 1;
            if (row != null) {
                boolean flag = true;
                Map<String, Object> map = new HashMap<>();

                // 主单号(0)
                String masterBillId = PoiUtil.getExcelCellValue(wb, row, 0);
                if (DataTypeUtil.isEmptyStr(masterBillId)) {
                    flag = false;
                    exceptionInfoStr.append("上传的excel文件中的【" + rowNum + "】行【主单号】为空<br/>");
                }


                // 代理送货费金额(2)
                Double amount = DataTypeUtil.toDouble(PoiUtil.getExcelCellValue(wb, row, 1), DEFAULT_AMOUNT, 2);
                if (amount.doubleValue() == DEFAULT_AMOUNT.doubleValue()) {
                    flag = false;
                    exceptionInfoStr.append("上传的excel文件中的【" + rowNum + "】行【金额】为空<br/>");
                }


                if (flag) {
                    map.put("masterBillId", masterBillId);
                    map.put("amount", amount);
                    listMap.add(map);
                }
            }
        }

        if (exceptionInfoStr.length() > SysConstant.INT_ZERO) {
            throwException(exceptionInfoStr.toString());
        }

        // 迭代处理
        StringBuilder nativeBillIds = new StringBuilder();
        for (Map<String, Object> map : listMap) {
            String masterBillId = DataTypeUtil.toNotNullString(map.get("masterBillId"));
            Double amount = DataTypeUtil.toDouble(map.get("amount"), DEFAULT_AMOUNT, 2);

            List<BNativeBillPojo> billPojoList = this.bNativeBillMapper.queryBNativeBillPojoListByMasterBillId(masterBillId);

            if (billPojoList == null ||  billPojoList.size() == 0 || billPojoList.size()>1 ) {
                exceptionInfoStr.append("【" + masterBillId + "】主单号包含的分单对象不存在或有多个分单对象<br/>");
                continue;
            }


            BNativeBillPojo bNativeBillPojo = billPojoList.get(0);

            Double agentDeliveryCharge = bNativeBillPojo.getAgentDeliveryCharge();
            if(agentDeliveryCharge.doubleValue() == amount.doubleValue()){
                nativeBillIds.append("'" + bNativeBillPojo.getId() + "',");
            }
            else {
                exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应金额【" + amount + "】与该主单对应分单【" + bNativeBillPojo.getId() + "】代理送货费金额【" + agentDeliveryCharge.doubleValue() + "】不一致<br/>");
            }

        }

        if (nativeBillIds.length() > SysConstant.INT_ZERO) {
            String updateNativeBillIds = nativeBillIds.substring(0, nativeBillIds.length() - 1);
            updateStatusId("agent_delivery_charge_account_check_status_id", SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId(), updateNativeBillIds, this.getSysTime(), this.getLoginCzyId());
        }

        return exceptionInfoStr.toString();
    }


    /**
     * 根据参数查询统计汇总
     * @param jsonObject
     * @return
     */
    public Map<String, Object> totalCalc(JSONObject jsonObject) {
        return bNativeBillMapper.totalCalc(jsonObject);
    }


}
